/**
 * Baijiahulian.com Inc. Copyright (c) 2014-2016 All Rights Reserved.
 */
package com.baijia.authentication.handler.support;

import com.baijia.authentication.handler.exception.AuthenticationException;
import com.baijia.authentication.principal.Credentials;
import com.baijia.authentication.principal.credentials.UserCredentials;
import com.baijia.dao.UserDao;
import com.baijia.dao.po.User;
import com.baijia.services.ServicesManager;
import com.baijia.util.JigouPasswordUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

/**
 * @title UserAuthenticationHandler
 * @desc TODO
 * @author macrohuang
 * @date Jan 20, 2016
 * @version 1.0
 */
@Component
public class UserAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {

    protected static String PREFIX = "user_mobile_";
    protected static String LOGIN_FAIL_TIMES = "user_login_fail_times";
    protected static String LOGIN_BAN_FLAG = "user_login_ban_flag";

    @Autowired
    protected UserDao userDao;
    @Autowired
    protected ServicesManager servicesManager;

    @Override
    protected boolean preAuthenticate(Credentials credentials) throws AuthenticationException {
        // 老师使用验证码，不使用封禁
        // UserCredentials userCredentials = (UserCredentials) credentials;
        // String banFlag = RedisUtil.hGet(PREFIX + userCredentials.getUsername(), LOGIN_BAN_FLAG);
        // if (StringUtils.isNotBlank(banFlag)) {
        // if (BooleanUtils.toBoolean(banFlag)) {
        // throw new UrlMessageException("banned", "账号已被锁定，请一小时后再试");
        // }
        // }

        return true;
    }

    @Override
    protected boolean postAuthenticate(Credentials credentials, boolean authenticated) throws AuthenticationException {
        // 老师使用验证码，不使用封禁
        // UserCredentials userCredentials = (UserCredentials) credentials;
        // if (!authenticated) {
        // RedisUtil.incrBy(PREFIX + userCredentials.getUsername(), LOGIN_FAIL_TIMES, 1L);
        // String failStr = RedisUtil.hGet(PREFIX + userCredentials.getUsername(), LOGIN_FAIL_TIMES);
        // long failTimes = Long.valueOf(failStr);
        // RegisteredServiceImpl service =
        // (RegisteredServiceImpl) servicesManager.findServiceBy(userCredentials.getAccountType());
        // if (failTimes >= service.getLoginMaxTimes()) {
        // RedisUtil.hSet(PREFIX + userCredentials.getUsername(), LOGIN_BAN_FLAG, Boolean.TRUE.toString(),
        // service.getBanSeconds());
        // } else if (failTimes >= service.getLoginNoticeTimes()) {
        // throw new UrlMessageException("badCredential", "账号或密码错误" + service.getLoginMaxTimes() + "次，还剩"
        // + (service.getLoginMaxTimes() - failTimes) + "次");
        // } else {
        // throw new UrlMessageException("badCredential", "账号或密码错误");
        // }
        // } else {
        // RedisUtil.del((PREFIX + userCredentials.getUsername()).getBytes());
        // }

        return authenticated;
    }

    @Override
    public boolean supports(Credentials credentials) {
        return credentials instanceof UserCredentials;
    }

    @Override
    protected boolean doAuthentication(Credentials credentials) throws AuthenticationException {
        UserCredentials userCredentials = (UserCredentials) credentials;
        // 机构的登录名是手机号
        String mobile = userCredentials.getUsername();
        String password = userCredentials.getPassword();
        User user = null;
        try {
            user = userDao.getUserByMobile(mobile); // FIXME 没判断用户是否存在
        } catch (Exception e) {
            return false;
        }

        try {
            return testLogin(password) || userCredentials.isSms()
                || JigouPasswordUtil.validatePassword(password, user.getPassword());
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            logger.error("valid user password error! mobile:{}", mobile, e);
            return false;
        }
    }
}
